// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using System.IO.IsolatedStorage;
using System.IO;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Devices.Sensors;
#endregion

namespace HexTD
{
	class GameplayScreen : GameScreen
	{
		#region Fields
		// Texture Members
		Texture2D sunsetTexture;
		SpriteFont hudFont;

		// Rendering members
		Vector2 cloud1Position;
		Vector2 cloud2Position;

		Vector2 playerHUDPosition;
		Vector2 computerHUDPosition;
		Vector2 windArrowPosition;

		// Gameplay members
		Context context;
		GameBoard gameBoard;
		string mapFileUrl;
		Human player;
		Vector2 wind;
		bool changeTurn;
		bool isHumanTurn;
		bool gameOver;
		Random random;
		const int minWind = 0;
		const int maxWind = 10;

		// Helper members
		bool isDragging;
		#endregion

		#region Initialization
		public GameplayScreen(string mapFileUrl)
		{
			EnabledGestures = GestureType.FreeDrag |
				GestureType.DragComplete |
				GestureType.Tap;

			this.mapFileUrl = mapFileUrl;
			random = new Random();
		}
		#endregion

		#region Content Loading/Unloading
		/// <summary>
		/// Loads the game assets and initializes "players"
		/// </summary>
		public override void LoadContent()
		{
			base.LoadContent();

			// Start the game
			Start();
		}

		public void LoadAssets()
		{
			// Load textures
			sunsetTexture = Load<Texture2D>("Textures/sunset");
			// Load font
			hudFont = Load<SpriteFont>("Fonts/HUDFont");

			// Define initial HUD positions
			playerHUDPosition = new Vector2(7, 7);
			computerHUDPosition = new Vector2(613, 7);
			windArrowPosition = new Vector2(345, 46);

			context = new Context(null, ScreenManager.Game);
			MapIO.readLevel(context, mapFileUrl);

			// Initialize human & AI players
			player = new Human(ScreenManager.Game, ScreenManager.SpriteBatch);
			player.Initialize();
			player.Name = "Player";

			gameBoard = new GameBoard(ScreenManager.Game, ScreenManager.SpriteBatch, context);
			gameBoard.Initialize();
		}
		#endregion

		#region Update
		/// <summary>
		/// Runs one frame of update for the game.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
		{
			float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

			// Update the players
			player.Update(gameTime);

			// Updates the clouds position
			UpdateClouds(elapsed);

			base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
		}
		#endregion

		#region Draw
		/// <summary>
		/// Draw the game world, effects, and HUD
		/// </summary>
		/// <param name="gameTime">The elapsed time since last Draw</param>
		public override void Draw(GameTime gameTime)
		{

			ScreenManager.SpriteBatch.Begin();

			// Render all parts of the screen
			DrawBackground();
			//DrawPlayer(gameTime);
			DrawHud();

			ScreenManager.SpriteBatch.End();

			gameBoard.Draw(gameTime);
		}
		#endregion

		#region Input
		/// <summary>
		/// Input helper method provided by GameScreen.  Packages up the various input
		/// values for ease of use.
		/// </summary>
		/// <param name="input">The state of the gamepads</param>
		public override void HandleInput(InputState input)
		{
			if (input == null)
				throw new ArgumentNullException("input");

			if (gameOver)
			{
				if (input.IsPauseGame(null))
				{
					FinishCurrentGame();
				}

				foreach (GestureSample gestureSample in input.Gestures)
				{
					if (gestureSample.GestureType == GestureType.Tap)
					{
						FinishCurrentGame();
					}
				}

				return;
			}

			if (input.IsPauseGame(null))
			{
				PauseCurrentGame();
			}

			// Read all available gestures
			foreach (GestureSample gestureSample in input.Gestures)
			{
				if (gestureSample.GestureType == GestureType.FreeDrag)
					isDragging = true;
				else if (gestureSample.GestureType == GestureType.DragComplete)
					isDragging = false;

				player.HandleInput(gestureSample);
			}
		}
		#endregion

		#region Update Helpers
		private void UpdateClouds(float elapsedTime)
		{
			// Move the clouds according to the wind
			var windDirection = wind.X > 0 ? 1 : -1;
		}
		#endregion

		#region Draw Helpers
		/// <summary>
		/// Draws the player's catapult
		/// </summary>
		void DrawPlayer(GameTime gameTime)
		{
			if (!gameOver)
				player.Draw(gameTime);
		}

		/// <summary>
		/// Draw the sky, clouds, mountains, etc. 
		/// </summary>
		private void DrawBackground()
		{
			// Clear the background
			ScreenManager.Game.GraphicsDevice.Clear(Color.White);

			// Draw the background
			ScreenManager.SpriteBatch.Draw(sunsetTexture, Vector2.Zero, Color.White);
		}

		/// <summary>
		/// Draw the HUD, which consists of the score elements and the GAME OVER tag.
		/// </summary>
		void DrawHud()
		{
			if (gameOver)
			{
				//Texture2D texture;

				//ScreenManager.SpriteBatch.Draw(
				//    texture,
				//    new Vector2(ScreenManager.Game.GraphicsDevice.Viewport.Width / 2 - texture.Width / 2,
				//                ScreenManager.Game.GraphicsDevice.Viewport.Height / 2 - texture.Height / 2),
				//    Color.White);
			}
			else
			{
				DrawString(hudFont, player.Score.ToString(),
					playerHUDPosition + new Vector2(123, 35), Color.White);
				DrawString(hudFont, player.Name,
					playerHUDPosition + new Vector2(40, 1), Color.Blue);

				// Draw Wind direction
				string text = "WIND";
				Vector2 size = hudFont.MeasureString(text);
				Vector2 windarrowScale = new Vector2(wind.Y / 10, 1);

				DrawString(hudFont, text,
					windArrowPosition - new Vector2(0, size.Y), Color.Black);
				if (wind.Y == 0)
				{
					text = "NONE";
					DrawString(hudFont, text, windArrowPosition, Color.Black);
				}

				if (isHumanTurn)
				{
					// Prepare human prompt message
					text = !isDragging ?
						"Drag Anywhere to Fire" : "Release to Fire!";
					size = hudFont.MeasureString(text);
				}
				else
				{
					// Prepare AI message
					text = "I'll get you yet!";
					size = hudFont.MeasureString(text);
				}

				DrawString(hudFont, text,
					new Vector2(
						ScreenManager.GraphicsDevice.Viewport.Width / 2 - size.X / 2,
						ScreenManager.GraphicsDevice.Viewport.Height - size.Y),
						Color.Green);
			}
		}

		/// <summary>
		/// A simple helper to draw shadowed text.
		/// </summary>
		void DrawString(SpriteFont font, string text, Vector2 position, Color color)
		{
			ScreenManager.SpriteBatch.DrawString(font, text,
				new Vector2(position.X + 1, position.Y + 1), Color.Black);
			ScreenManager.SpriteBatch.DrawString(font, text, position, color);
		}

		/// <summary>
		/// A simple helper to draw shadowed text.
		/// </summary>
		void DrawString(SpriteFont font, string text, Vector2 position, Color color, float fontScale)
		{
			ScreenManager.SpriteBatch.DrawString(font, text, new Vector2(position.X + 1,
				position.Y + 1), Color.Black, 0, new Vector2(0, font.LineSpacing / 2),
				fontScale, SpriteEffects.None, 0);
			ScreenManager.SpriteBatch.DrawString(font, text, position, color, 0,
				new Vector2(0, font.LineSpacing / 2), fontScale, SpriteEffects.None, 0);
		}
		#endregion

		#region Input Helpers
		/// <summary>
		/// Finish the current game
		/// </summary>
		private void FinishCurrentGame()
		{
			ExitScreen();
		}

		/// <summary>
		/// Pause the current game
		/// </summary>
		private void PauseCurrentGame()
		{
			var pauseMenuBackground = new BackgroundScreen();

			if (isDragging)
			{
				isDragging = false;
				//player.Catapult.CurrentState = CatapultState.Idle;
			}

			ScreenManager.AddScreen(pauseMenuBackground, null);
			ScreenManager.AddScreen(new PauseScreen(pauseMenuBackground), null);
		}
		#endregion

		#region Gameplay Helpers
		/// <summary>
		/// Starts a new game session, setting all game states to initial values.
		/// </summary>
		void Start()
		{
			// Set initial wind direction
			wind = Vector2.Zero;
			isHumanTurn = false;
			changeTurn = true;
		}
		#endregion
	}
}
